package org.jeecg.modules.sxaq.ior.service.impl;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jeecg.boot.starter.rabbitmq.client.RabbitMqClient;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.sxaq.deviceinfo.entity.DeviceInfo;
import org.jeecg.modules.sxaq.deviceinfo.service.IDeviceInfoService;
import org.jeecg.modules.sxaq.ior.entity.RecordInout;
import org.jeecg.modules.sxaq.ior.mapper.RecordInoutMapper;
import org.jeecg.modules.sxaq.ior.service.IRecordInoutService;
import org.jeecg.modules.sxaq.utils.RabbitMQConstant;
import org.jeecg.modules.sxaq.utils.RedisConstant;
import org.jeecg.modules.sxaq.utils.Urls;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.entity.SysUserDevice;
import org.jeecg.modules.system.service.ISysUserDeviceService;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import javax.transaction.Transactional;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @Description: 进出场记录
 * @Author: DHC
 * @Date: 2020-12-01
 */
@Slf4j
@Service
public class RecordInoutServiceImpl extends ServiceImpl<RecordInoutMapper, RecordInout> implements IRecordInoutService {

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private ISysUserDeviceService sysUserDeviceService;

    @Autowired
    private RabbitMqClient rabbitMqClient;

    @Autowired
    private RedisUtil redisUtil;

    @Value("${sxaq.redisUploadTime}")
    private String redisUploadTime;

    @Value("${sxaq.cloudUrl}")
    private String cloudUrl;

    @Value("${sxaq.factoryCode}")
    private String factoryCodeDefine;

    @Autowired
    private IDeviceInfoService deviceInfoService;

    @Autowired
    private RecordInoutMapper recordInoutMapper;

    @Transactional
    @Override
    public Result entranceAndExit1(JSONObject jsonObject) {
        return deal(1, jsonObject);
    }

    @Transactional
    @Override
    public Result entranceAndExit2(JSONObject jsonObject) {
        return deal(2, jsonObject);
    }

    private Result<?> deal(int entranceAndExitType, JSONObject jsonObject) {
        String workNo = jsonObject.getString("workNo");
        String scanName = jsonObject.getString("scanName");
        String scanCode = jsonObject.getString("scanCode");
        String mobile_single = jsonObject.getString("mobileSingle");
        int type = Integer.parseInt(jsonObject.getString("type"));
        String factoryCode = jsonObject.getString("factoryCode");
        if (!factoryCode.equals(factoryCodeDefine)) {
            return Result.error("工厂CODE不正确！");
        }

        // eventTime来自手机，手机获取的云服务器时间。
        // eventTime来自web，直接取本地服务器时间
        String timeS = jsonObject.getString("eventTime");
        long eventTime = 0;
        if ("".equals(timeS) || timeS == null) {
            return Result.error("事件时间无效！");
        } else {
            eventTime = Long.parseLong(timeS);
        }

        String redisData = (String) redisUtil.get(RedisConstant.IN_OUT_RECORD + workNo);
        if (redisData != null) {
            String[] data = redisData.split("/", 2);
            int redisType = Integer.parseInt(data[0]);
            long redisTime = Long.parseLong(data[1]);
            if (redisTime == eventTime) {
                return Result.error("重复扫码！");
            }
//            if (redisType == type) {
//                return Result.error(type == 1 ? "重复进场！" : "重复出场！");
//            }
        }

        // 更新redis进出场状态
        redisUtil.set(RedisConstant.IN_OUT_RECORD + workNo, type + "/" + eventTime);

        log.info("----扫码请求----接收----" + new Date(System.currentTimeMillis()) + "，员工：" + workNo);
        JSONObject jsonObject1 = new JSONObject();
        jsonObject1.put("workNo", workNo);
        jsonObject1.put("mobileSingle", mobile_single);
        jsonObject1.put("type", "scan");
        jsonObject1.put("factoryCode", factoryCode);
        jsonObject1.put("force", false);

        SysUser sysUser = sysUserService.getUserByWorkNo(workNo);
        if (sysUser == null) {
            jsonObject1.put("isSuccess", false);
            JSONObject obj = new JSONObject();
            obj.put("type", type);
            obj.put("message", "1");
            jsonObject1.put("inoutObject", Result.OK(obj));
            return check(entranceAndExitType, jsonObject1);
        }

        SysUserDevice sysUserDevice = sysUserDeviceService.querySysUserDevice(workNo, mobile_single);

        // 进场校验二维码时效性，当前时间大于二维码生成时间60秒，二维码失效
//        long currentTime = System.currentTimeMillis();
//        if (currentTime - eventTime > 30 * 1000) {
//            jsonObject1.put("isSuccess", false);
//            JSONObject obj = new JSONObject();
//            obj.put("type", type);
//            obj.put("message", "2");
//            jsonObject1.put("inoutObject", Result.OK(obj));
//            return check(entranceAndExitType, jsonObject1);
//        }

        // 添加进场记录
        RecordInout recordInout = new RecordInout();
        recordInout.setType(type);
        recordInout.setPhone(sysUser.getPhone());
        recordInout.setUserId(sysUser.getId());
        recordInout.setUsername(sysUser.getUsername());
        recordInout.setRealname(sysUser.getRealname());
        recordInout.setWorkNo(workNo);
        recordInout.setScanName(scanName);
        recordInout.setScanCode(scanCode);
        recordInout.setEventTime(new Date(eventTime));
        DeviceInfo deviceInfo = deviceInfoService.getDeviceBySingle(mobile_single);
        recordInout.setMobileModel(deviceInfo.getMobileModel());
        recordInout.setMobileSystem(deviceInfo.getMobileSystem());
        recordInout.setMobileVersion(deviceInfo.getMobileVersion());
        recordInout.setMobileSingle(deviceInfo.getMobileSingle());
        recordInout.setPassword("");
        save(recordInout);

        // 更新用户进出场事件，用于大屏统计
        sysUser.setEventType(type);
        sysUserService.updateById(sysUser);

        // 更新设备信息
        if (sysUserDevice != null) {
            sysUserDevice.setEventType(type);
            sysUserDeviceService.updateById(sysUserDevice);
        }

        // 成功
        JSONObject inoutObject = (JSONObject) JSONObject.toJSON(recordInout);
        jsonObject1.put("isSuccess", true);
        jsonObject1.put("inoutObject", Result.OK(inoutObject));

        return check(entranceAndExitType, jsonObject1);
    }

    private Result<?> check(int entranceAndExitType, JSONObject jsonObject1) {
        // type 1实际上线操作， 2APP测试按钮操作
        if (entranceAndExitType == 1) {
            JSONObject json = doPost(cloudUrl + Urls.GUN, jsonObject1);
            if (json != null) {
                boolean success = json.getBoolean("success");
                String message = json.getString("message");
                if (success) {
                    // 开闸门
                    log.info("----扫码请求----反馈----成功----");
                    return Result.OK("操作成功！");
                } else {
                    log.info("----扫码请求----反馈----失败----");
                    return Result.error(message);
                }
            } else {
                log.info("----扫码请求----反馈----失败----");
                return Result.error("请求失败！");
            }
        } else {
            // 这个是APP端测试用的扫枪按钮
            rabbitMqClient.sendMessageToExchange(RabbitMQConstant.CLOUD_INOUT_EXCHANGE, RabbitMQConstant.CLOUD_INOUT_KEY + jsonObject1.getString("factoryCode"), jsonObject1.toString());
            return Result.OK("操作成功！");
        }
    }

    public JSONObject doPost(String url, JSONObject data) {
        HttpClient client = HttpClients.createDefault();

        // 要调用的接口方法
        HttpPost post = new HttpPost(url);
        JSONObject jsonObject = null;
        try {
            StringEntity s = new StringEntity(data.toString());
            s.setContentEncoding("UTF-8");
            s.setContentType("application/json");
            post.setEntity(s);
            post.addHeader("content-type", "application/json; charset=utf-8");
            HttpResponse res = client.execute(post);
            String response1 = EntityUtils.toString(res.getEntity());
            jsonObject = JSONObject.parseObject(response1);
            System.out.println(response1);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return jsonObject;
    }

    @Override
    public List<HashMap<String, String>> getInoutCount(String begin, String end, int type) {
        return recordInoutMapper.queryInoutCount(begin, end, type);
    }
}
